{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<center>\n",
    "<img src=\"../../img/ods_stickers.jpg\">\n",
    "## Открытый курс по машинному обучению\n",
    "<center>Автор материала: Валентина Бирюкова (@myltykritik)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# _«Сделай это красиво...»_\n",
    "\n",
    "Как можно сделать вашу презентацию и графики более красивыми?\n",
    "Хочу предложить два варианта:\n",
    "* Делать все в определенной цветовой гамме;\n",
    "* Использовать уже готовые красивые графики вместо базовых.\n",
    "\n",
    "В этом туториале коснемся и первого, и второго пункта.\n",
    "\n",
    "## Цвет\n",
    "Что нам дает цвет? \n",
    "* Во-первых, цветом очень хорошо выделять информацию, именно поэтому, например, для тепловых карт используются цветовые схемы, которые отличаются от схем для графиков со столбцами.\n",
    "* Во-вторых, хорошо оформленные материалы повышают восприятие и удовольствие от просмотра. Если все делать в разной стилистике и кое-как оформленным, то положительной реакции не стоит ждать.\n",
    "\n",
    "Я, например, когда мне надо оформить работу, сначала смотрю на [Цветовое колесо](https://color.adobe.com/) и заранее выбираю цвет оформления презентации, если там будет хотя бы несколько графиков. Для совсем официальных и деловых — это голубые цвета. Для менее официальных — это зеленые или золотые оттенки. Но дай мне волю и я всё буду делать в розовых оттенках :)\n",
    "Чаще всего для оформления подходят монохромные или комплементарные схемы, но каждая для своих типов графиков.\n",
    "\n",
    "Монохромная схема хороша, когда вам надо показать градации одной величины в рамках пары параметров: например, распределения плотности.\n",
    "\n",
    "Комплементарные хороши, например, в тепловых картах, где значение корреляции каждой пары из множества признаков может быть в дипазоне [-1, 1]. Или если не корреляция, а сводная таблица, и данные имеют центр распределения и хочется показать, что часть значений сильно меньше центра, а часть больше.\n",
    "\n",
    "Но иногда нужны просто наборы цветов, если надо показать, напрмер, продажи нескольких товаров на столбчатом графике. Значения между собой особо не зависимы, так что цветом зависимость не надо подчеркивать. Но и тут нужно подбирать цвета, подходящие под общую стилистику: например, пастельные или, наоборот, яркие.\n",
    "\n",
    "Далее мы увидим примеры под каждый из способов и посмотрим, как что задать с помощью библиотек Python. Для примеров я выбрала пакет seaborn. Очень советую его попробовать. Это надстройка над mathplotlib, изначально делающая симпатичные графики и позволяющая их еще больше улучшать и кастомизировать.\n",
    "\n",
    "В этом туториале мы поработаем с цветом, обсудим какие схемы для чего нужны, потом построим несколько красивых графиков на все случаи жизни и посмотрим, какие выводы можно делать из графического представления данных. В конце будет пример визуализации данных 'mlbootcamp5_train.csv'- про сердечно-сосудистые заболевания, выполненный в одной цветовой гамме и с пройденными графиками (Приложение 2).\n",
    "\n",
    "В этом туториале не будет очень подробных разъяснений как работает тот или иной график. Будем лишь частично касатся технической стороны, по большей степени о цвете. Также не будет моделей. Только визуализации.\n",
    "\n",
    "А сейчас для начала загрузим два набора данных: 'vgsales.csv' - продажи игр, 'data.csv' - рейтинги игр. И немного их предобработаем для корректного использования."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import seaborn as sns\n",
    "\n",
    "%matplotlib inline\n",
    "sns.set(style = 'darkgrid') #зададим базовое оформление\n",
    "\n",
    "data = pd.read_csv('../../data/vgsales.csv')\n",
    "data.dropna(inplace=True)\n",
    "data['Year'] = data['Year'].apply(lambda x: int(x))\n",
    "# data['Platform'] = data['Platform'].apply(lambda x: str(x))\n",
    "data = data[data['Year'] < 2017]\n",
    "data_sales = data[data['Year'] == 2016][['NA_Sales', 'EU_Sales', 'JP_Sales', 'Other_Sales']] #данные по продажам в 4 регинах\n",
    "data_years = data[((data['Year'] == 2014)|(data['Year'] == 2015)|(data['Year'] == 2016))&((data['Platform'] == 'PS4')|(data['Platform'] == 'WiiU')|(data['Platform'] == 'XOne'))][['Global_Sales', 'Platform', 'Year']]\n",
    "\n",
    "score = pd.read_csv('../../data/scores.csv')\n",
    "score.dropna(inplace=True)\n",
    "score['Critic_Score'] = score['Critic_Score'].apply(lambda x: float(x))\n",
    "score['User_Score'] = score['User_Score'].apply(lambda x: float(x))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Начнем с графика виолончель. Построим его по продажам игр 4 регионов. Величины даны в миллионах штук. Но для этого посмотрим, какие данные у нас по продажам есть. Возьмем колонку с самыми большими продажами: 'NA_Sales'. Построим распределение и log(x+1) распределение данных. Видим, что данные не очень приятные: немного больших значений и очень длинный хвост из маленьких значений. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "plt.figure(1, figsize=(5, 5))\n",
    "plt.subplot(211)\n",
    "plt.plot(data['NA_Sales'], 'o')\n",
    "plt.subplot(212)\n",
    "plt.plot(data['NA_Sales'].apply(lambda x: np.log1p(x)), 'o')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Значений с продажами менее 0.5 почти 87%. Вот их и возьмем и построим по ним виолончели."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "data_small= data[data['NA_Sales'] < 0.5]\n",
    "print(data.shape, data_small.shape)\n",
    "data_small.shape[0]/data.shape[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Построим первый график, так сказать, из коробки, без всяких улучшений.\n",
    "Видим, что он и так не плох, но не идеален."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sns.violinplot(data = data_sales[data_sales < 0.5], inner='box')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Теперь мы добрались до улучшения графиков и подбора цветов.\n",
    "\n",
    "В seaborn есть несколько способов задавать цвета:\n",
    "* Использовать стандартные обозначения 'g' - green, 'm' - magenta и т.д;\n",
    "* Использовать rgb (0.1, 0.33, 1.) или дроби для rgb (36/255, 127/225, 213/255), так как в том же цветовом колесе значения rgb в диапазоне от 1 до 255, а в seaborn надо от 0 до 1;\n",
    "* Использовать встроенные палитры. Вот это самый удобный способ, потому что палитры уже достаточно хорошо подобранные и проверенные временем. Ниже, в Приложении 1, выведены все доступные палитры. Я туда частенько заглядывала при написании туториала, выбирая, какие оттенки голубого или розового брать.\n",
    "\n",
    "В каждом из графиков у вас попросят color, palette или cmap. На примерах рассмотрим различия.\n",
    "\n",
    "Итак, начнем красить наши виолончели и делать их красивыми.\n",
    "\n",
    "* Возьмем палитру 'viridis'. Это последовательные цвета: фиолетовый переходит в желто-зеленый;\n",
    "* Далее добавим оформление графика: style = 'white'. Есть ещё 'whitegrid', 'dark', 'darkgrid' и 'ticks'. С большинством мы тут познакомимся;\n",
    "* Увеличим размер картинки: это задается в plt.subplots и параметру figsize передается пара значений размера в дюймах;\n",
    "* Подберем размер надписей, просто это сделать скалированием шрифта: font_scale=1.5;\n",
    "* Все это аккуратно передадим в настройки графика и вуаля!\n",
    "\n",
    "Для подобных графиков так же бы подошел и монотон."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sns_plot = sns.palplot(sns.color_palette('viridis'))\n",
    "sns_plot = sns.palplot(sns.color_palette('BuGn'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sns.set(style = 'white', font_scale=1.5)\n",
    "c =  sns.color_palette('viridis')\n",
    "fig, ax = plt.subplots(figsize=(15, 8))\n",
    "sns.violinplot(ax = ax, data = data_sales[data_sales < 0.5], inner='box', palette=c)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Помимо плавно переходящих оттенков бывают наборы просто разных цветов, но, например, одной яркости или насыщенности.\n",
    "Такие цветовые схемы хороши, когда на одном графики надо выделить одинаковые элементы и показать, что они отличаются от других элементов. Как в примере, где у нас данные по трем игровым платформам, глобальным продажам и за три года. Цвет сразу показывает, где одинаковые элементы в каждом году и где разные внутри одного года.\n",
    "\n",
    "Еще в seaborn есть две опции: если добавить в название к цвету '\\_d' (dark), то оттенки будут темнее и переделаны так, что переходы между ними будут менее резкими. Если добвить '\\_r' (reverse), то цвета будут идти в обратном порядке."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sns.set(style = 'darkgrid')\n",
    "sns_plot = sns.palplot(sns.color_palette('Accent'))\n",
    "sns_plot = sns.palplot(sns.color_palette('Accent_r'))\n",
    "sns_plot = sns.palplot(sns.color_palette('Accent_d'))\n",
    "sns_plot = sns.palplot(sns.color_palette('CMRmap'))\n",
    "sns_plot = sns.palplot(sns.color_palette('Set1'))\n",
    "sns_plot = sns.palplot(sns.color_palette('Set3'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sns.set(style = 'whitegrid', font_scale=1.4)\n",
    "fig = plt.subplots(figsize=(15, 8))\n",
    "ax = sns.barplot(x = 'Year', y = 'Global_Sales', hue = 'Platform', data = data_years, palette='Set3_r', ci = None)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "В отдельную группу (и функцию sns.cubehelix_palette) выделины специальные наборы цветов, которые представляют из себя один оттенок, с линейно увеличивающейся (или уменьшающейся) яркостью. Это свойство позволяет печатать графики в оттенках серого без потери читабельности. А также позволяет читать их людям, которые не различают цвета.\n",
    "\n",
    "sns.cubehelix_palette настраивается разнообразными способами, можно задать любой базовый оттенок, любую насыщенность и яркость, а также, количество цветов, которое потребуется для отрисовки графика (автоматически тоже работает, но лучше указывать, если известно заранее, потому что, таким образом, будут предложены наиболее контрастные варианты).\n",
    "\n",
    "Выгоду этот набор приносит, например, в тепловых картах, на что мы посмотрим ниже."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sns.set(style = 'darkgrid')\n",
    "sns_plot = sns.palplot(sns.cubehelix_palette(start=0, rot = 0.5, gamma = 1, hue= 1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sns.set(style = 'dark', font_scale=1.5)\n",
    "c =  sns.cubehelix_palette(n_colors=4, start=0, rot = 0.5, gamma = 1, hue= 1)\n",
    "fig, ax = plt.subplots(figsize=(15, 8))\n",
    "sns.violinplot(ax = ax, data = data_sales[data_sales < 0.5], inner='box', palette=c)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Выше были представлены оформления: white, whitegrid и dark. Каждый подходит для своих нужд и можно экспериментировать, что вам больше нравится. \n",
    "\n",
    "Также, вы могли заметить, что во всех примерах был параметр palette. Ему всегда передается сразу список цветов. Параметру color передается один цвет, но потом в самом графике ему могут добавляться оттенки, как это бывает в jointplot. Cmap используется тогда, когда о данных ничего не известно и не ясно, сколько и каких цветов может потребоваться. Функциям типа cubehelix_palette нужно напрямую передавать параметр as_cmap=True, а разные наборы цветов из Приложения 1 можно использовать и так."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Графики\n",
    "\n",
    "Теперь плавно перейдем к теме красивых готовых графиков.\n",
    "\n",
    "«Сделай мне красиво» — может оказаться головной болью, если поджимает время или чувство прекрасного напрочь утрачено. Но и тут помогут встроенные в seaborn готовые графики. А я лишь немного о них расскажу.\n",
    "\n",
    "Любой scatter plot украсят шестиугольники — просто добавьте kind='hex'. А также распределения используемых в нем величин. \n",
    "\n",
    "Но с цветами придется немного повозиться. Парметру color можно передать традиционные 'r' и 'g', но это не интресно. Но можно выбрать любую нравящуюся вам палитру, посмотреть, как график выглядит при каждом из цветов и передать параметру color именно его. Мне очень нравится палитра 'spring', так что тут я использую ее.\n",
    "\n",
    "На графиках виден явный тренд и место основного скопления пар оценок. Можно сказать, что и критики, и пользователи больше всего ставят оценок, равных 80% от максимума."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sns.set(style='darkgrid')\n",
    "sns_plot=sns.palplot(sns.color_palette('spring_d'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "for i in range(2, 5):\n",
    "    sns.set(font_scale=1, style=\"white\")\n",
    "    c =  sns.color_palette('spring_d')[i]\n",
    "    sns_jointplot = sns.jointplot('Critic_Score', 'User_Score', data=score, kind='hex', color=c, size=6, stat_func=None)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Графики плотности тут тоже хороши. Для них можно выбрать как один из полученных ранее цветов, так и любой rgb. Главное, помнить, что rgb цвета должны быть в пределах от 0 до 1."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sns.set(font_scale=1, style=\"darkgrid\")\n",
    "c =  sns.color_palette('spring_d')[4]\n",
    "sns_jointplot = sns.jointplot('Critic_Score', 'User_Score', data=score, kind='kde', color=c, size=6)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sns.set(font_scale=1, style=\"darkgrid\")\n",
    "c =  sns.color_palette('viridis')[3]\n",
    "sns_jointplot = sns.jointplot('Critic_Score', 'User_Score', data = score, kind='kde', color = (26/255, 191/255, 181/255), size=6)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Теперь настала очередь красивых корреляционных матриц.\n",
    "\n",
    "Тут полезны, так называемые diverging_palette (расходящиеся цвета), также вынесенные в отдельную функцию. Важно задать цвет минимального значения, максимального значения, будет ли центр ярким или, наоборот, темным и некоторые другие характеристики. И еще нужно не забыть указать параметр as_cmap=True, чтобы тепловой карте передался colormap, а не список цветов.\n",
    "\n",
    "Подобными характеристиками обладают и некоторые наборы цветов, например cmap='coolwarm'. А в некоторых готовых наборах центр, наоборот черный. В diverging_palette тоже можно это задать.\n",
    "\n",
    "На графике наглядно видно, между какими парами признаков положительные или отрицательные, маленькие или большие корреляции. Центр задался автоматически в районе 0.35-0.4, так как максимальное значение 1, а минимальное только -0.25."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sns.set(style = 'darkgrid')\n",
    "sns_plot = sns.palplot(sns.diverging_palette(220, 10))\n",
    "sns_plot = sns.palplot(sns.color_palette('coolwarm'))\n",
    "sns_plot = sns.palplot(sns.color_palette('icefire'))\n",
    "sns_plot = sns.palplot(sns.diverging_palette(220, 10, center='dark'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "data_corr = score[['Year_of_Release', 'NA_Sales', 'EU_Sales', 'JP_Sales', 'Other_Sales', 'Critic_Score', 'Critic_Count', 'User_Score', 'User_Count']]\n",
    "corr = data_corr.corr()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sns.set(font_scale=1.5)\n",
    "cmap = sns.diverging_palette(220, 10, as_cmap=True)\n",
    "f, ax = plt.subplots(figsize=(15, 8))\n",
    "sns.heatmap(corr, cmap=cmap, annot=True, ax=ax, fmt='.2f')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "В seaborn также можно делать очень наглядные сводные таблицы. И раскрашивать их двумя способами:\n",
    "* Опять же идти от маленького значения через центр, который можно указать самостоятельно, к наибольшему значению (первая раскраска);\n",
    "* И идти от маленького значения к большему, наращивая насыщенность цвета (вторая раскраска с замечательным названием 'inferno').\n",
    "\n",
    "И в первой, и во второй сводной таблице очень много маленьких значений и небольшое количество больших значений. Есть пропуски."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sns.set(style = 'darkgrid')\n",
    "sns_plot = sns.palplot(sns.color_palette('RdGy_r'))\n",
    "sns_plot = sns.palplot(sns.color_palette('inferno_r'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fl = pd.pivot_table(data, values='JP_Sales', index='Genre', columns='Year')\n",
    "sns.set(font_scale=1)\n",
    "f, ax = plt.subplots(figsize=(20, 10))\n",
    "sns.heatmap(fl, annot=True, fmt=\".1f\", linewidths=.5, ax=ax, cmap = 'RdGy_r', center=0.6)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fl = pd.pivot_table(data,values='Global_Sales',index='Genre',columns='Platform')\n",
    "sns.set(font_scale=1)\n",
    "f, ax = plt.subplots(figsize=(20, 10))\n",
    "sns.heatmap(fl, annot=True, fmt=\".1f\", linewidths=.5, ax=ax, cmap = 'inferno_r')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "И напоследок, моя любимая визуализация пропусков в данных.\n",
    "\n",
    "Ведь порой важно знать не только сколько у тебя пропусков в данных, но и как они распределены.\n",
    "\n",
    "Здесь лучше всего выбирать разные по яркости цвета. Например, синий и красный не подойдут, потому что будет очень сложно разглядеть тонкие красные полосочки на темном синем фоне.\n",
    "\n",
    "Сразу видно, что в части с оценками у нас больше пропусков. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "score = pd.read_csv('../../data/scores.csv')\n",
    "sns.set(font_scale=2)\n",
    "fig, ax = plt.subplots(figsize=(25,15))\n",
    "sns_heatmap = sns.heatmap(score.isnull(),yticklabels=False,cbar=False,cmap='OrRd')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Спасибо за внимание! Теперь ваши презентации будут не только информативными, но и красивыми, выполненными в одном стиле и цвете.\n",
    "На этом можно закрыть туториал, а можно почитать Приложение 2, где я для примера делаю визуальный анализ данных про сердечно-сосудистые заболевания в одном стиле.\n",
    "\n",
    "А еще можно поставить + и написать комментарий под постом :)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Приложение 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "k = 'Accent, Accent_r, Blues, Blues_r, BrBG, BrBG_r, BuGn, BuGn_r,\\\n",
    "BuPu, BuPu_r, CMRmap, CMRmap_r, Dark2, Dark2_r, GnBu, GnBu_r, Greens,\\\n",
    "Greens_r, Greys, Greys_r, OrRd, OrRd_r, Oranges, Oranges_r, PRGn, \\\n",
    "PRGn_r, Paired, Paired_r, Pastel1, Pastel1_r, Pastel2, Pastel2_r, \\\n",
    "PiYG, PiYG_r, PuBu, PuBuGn, PuBuGn_r, PuBu_r, PuOr, PuOr_r, PuRd, \\\n",
    "PuRd_r, Purples, Purples_r, RdBu, RdBu_r, RdGy, RdGy_r, RdPu, RdPu_r, \\\n",
    "RdYlBu, RdYlBu_r, RdYlGn, RdYlGn_r, Reds, Reds_r, Set1, Set1_r, Set2, \\\n",
    "Set2_r, Set3, Set3_r, Spectral, Spectral_r, tab20c, \\\n",
    "Wistia, Wistia_r, YlGn, YlGnBu, \\\n",
    "YlGnBu_r, YlGn_r, YlOrBr, YlOrBr_r, YlOrRd, YlOrRd_r, afmhot, afmhot_r, \\\n",
    "autumn, autumn_r, binary, binary_r, bone, bone_r, brg, brg_r, bwr, bwr_r, \\\n",
    "cool, cool_r, coolwarm, coolwarm_r, copper, copper_r, cubehelix, \\\n",
    "cubehelix_r, flag, flag_r, gist_earth, gist_earth_r, gist_gray, \\\n",
    "gist_gray_r, gist_heat, gist_heat_r, gist_ncar, gist_ncar_r, \\\n",
    "gist_rainbow, gist_rainbow_r, gist_stern, gist_stern_r, gist_yarg,\\\n",
    "gist_yarg_r, gnuplot, gnuplot2, gnuplot2_r, gnuplot_r, gray, gray_r, \\\n",
    "hot, hot_r, hsv, hsv_r, icefire, icefire_r, inferno, inferno_r, magma, \\\n",
    "magma_r, mako, mako_r, nipy_spectral, nipy_spectral_r, ocean, ocean_r, \\\n",
    "pink, pink_r, plasma, plasma_r, prism, prism_r, rainbow, rainbow_r, \\\n",
    "rocket, rocket_r, seismic, seismic_r, spring, \\\n",
    "spring_r, summer, summer_r, tab10, tab10_r, tab20, tab20_r, tab20b, \\\n",
    "tab20b_r, tab20c, tab20c_r, terrain, terrain_r, viridis, viridis_r, \\\n",
    "vlag, vlag_r, winter, winter_r'\n",
    "k = ' '.join(k.split('_r'))\n",
    "k = ' '.join(k.split(','))\n",
    "k = k.split()\n",
    "k.remove('gist')\n",
    "k.remove('gist')\n",
    "k.remove('ainbow')\n",
    "k.remove('ainbow')\n",
    "k.append('gist_rainbow')\n",
    "sns.set(style = 'whitegrid')\n",
    "for i in list(sorted(set(k))):\n",
    "    print(i)\n",
    "    sns_plot = sns.palplot(sns.color_palette(i))\n",
    "#     sns_plot.savefig(i+'.png')\\"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Приложение 2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Скачаем данные по сердечно-сосудистым заболеваниям и проведем первичный визуальный анализ. Использовать будем желто-зелено-синюю цветовую схему."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sns.set(style = 'white', font_scale=1.5) #зададим базовое оформление\n",
    "df = pd.read_csv('../../data/mlbootcamp5_train.csv', sep=';', index_col='id')\n",
    "df = df.reset_index()\n",
    "df.drop('id', axis=1, inplace=True)\n",
    "df['age'] = df['age'].apply(lambda x: int(x/365))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fig, ax = plt.subplots(figsize=(10, 6))\n",
    "sns_heatmap = sns.heatmap(df.isnull(),yticklabels=False,cbar=False, cmap='YlGnBu')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Радует, что пропусков нет. А как дела с чистотой данных?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "c =  sns.color_palette('YlGnBu')[2]\n",
    "sns_jointplot = sns.jointplot('height', 'weight', data = df, kind='hex', size=6, color=c)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Маленькая картинка и большое пустое пространство говорят о том, среди данных о росте и весе есть выбросы. Что же, поставим на свое усмотрение наиболее логичные границы. Этеншн! Скорее всего, просто удалять данные не стоит, а лучше их обработать, но для наглядности мы их удалим, чтобы проверить гипотезу, что выбросы есть."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df = df[(df['height'] > 130)&(df['height'] < 200)]\n",
    "df = df[(df['weight'] > 40)&(df['weight'] < 140)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "c =  sns.color_palette('YlGnBu')[2]\n",
    "sns_jointplot = sns.jointplot('height', 'weight', data = df, kind='hex', size=6, color=c)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "Да, так и есть, выбросы были.\n",
    "\n",
    "Посмотрим далее на верхнее и нижнее давление."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "c =  sns.color_palette('YlGnBu')[2]\n",
    "sns_jointplot = sns.jointplot('ap_lo', 'ap_hi', data = df, kind='hex', size=6, color=c)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Похоже, тут совсем беда и есть невероятно огромные значения. Опять для наглядности просто удалим их, а впоследствии вернемся и обработаем (но уже не в этом туториале!)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df = df[(df['ap_lo'] > 40)&(df['ap_lo'] < 180)]\n",
    "df = df[(df['ap_hi'] > 50)&(df['ap_hi'] < 200)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "c =  sns.color_palette('YlGnBu')[2]\n",
    "sns_jointplot = sns.jointplot('ap_lo', 'ap_hi', data = df, kind='hex', size=6, color=c)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Так намного лучше и корреляция стала выше.\n",
    "\n",
    "Посмотрим на виолончели данных веса, роста и давления."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df1 = df[['height', 'weight', 'ap_lo', 'ap_hi']]\n",
    "fig, ax = plt.subplots(figsize=(15, 8))\n",
    "sns.violinplot(ax = ax, data = df1, inner='box', palette='YlGnBu')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Медианное значение роста около 165 см, веса - 75 кг, нижнего артериального давления - 80 мм ртутного столба, верхнего - 120 мм ртутного столба. \n",
    "\n",
    "Теперь поиграемся с данными и посмотрим, есть ли разница в весе у пьющих и непьющих представителей разных полов."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fig, ax = plt.subplots(figsize=(15, 8))\n",
    "sns.violinplot(x = 'gender', y = 'weight', ax = ax, data = df, hue='alco', inner='box', palette='YlGnBu')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Выходит, что непьющие женщины имеют медианный вес меньше, чем пьющие. А у мужчин такой явной разницы нет.\n",
    "\n",
    "Подобные графики можно строить на любые тройки данных: вес, рост, давление, пол, активность, курение, алкоголь и т.д.\n",
    "\n",
    "Пришло время гафика корреляций."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "corr = df.corr()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "f, ax = plt.subplots(figsize=(15, 8))\n",
    "sns.heatmap(corr, cmap='YlGnBu', annot=True, ax=ax, fmt='.1f')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Видим, между какими парами фич есть корреляция, а между какими нет. Значимой отрицательной корреляции нет почти негде. \n",
    "\n",
    "Вот так, достаточно просто и быстро можно построить красивую визуализацию к вашему проекту или презентации.\n",
    "\n",
    "Плюсики и комментарии приветствуются :)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
